import { catchError, map } from 'rxjs/operators'
import { ajax } from 'rxjs/ajax'
import environment from '@/environment'
import store from '@/store'
// import { of } from 'rxjs'

// 假数据
// import fakeUser from '@/fixtures/user'

const apiService = new class ApiService {

  get(url, headers = null) {
    return this.buildHttpRequest(url, 'GET', headers)
  }

  post(url, body = null, headers = null) {
    return this.buildHttpRequest(url, 'POST', body, headers)
  }

  put(url, body = null, headers = null) {
    return this.buildHttpRequest(url, 'PUT', body, headers)
  }

  delete(url, headers = null) {
    return this.buildHttpRequest(url, 'DELETE', headers)
  }

  // options 为 ajax 的其它设置, 直接倒进去
  buildHttpRequest(url, method = 'GET', body = null, headers = null, options = null) {

    url = url.startsWith('http') ? url : environment.api_endpoint + url

    // 如果有 token 就把 token 加到后续的请求 url 里
    const apiToken = store.state.auth.api_token

    return ajax({
      url,
      method,
      body,
      headers: {
        'content-type': 'application/json',
        'accept': 'application/json',

        // 'Authorization': `Bearer ${apiToken}`,
        'ACCESS_TOKEN': apiToken, // WARNING: 注意, 不同项目用的字段名可能不一样

        ...(headers ? headers : {}),
      },
      ...options,
    }).pipe(
      map(this.extractData),
      catchError(this.handleError),
    )
  }

  /**
   * 取出数据, 有错误就抛出
   * @param res
   */
  extractData(res) {

    // 响应基本样式
    // {
    //   code: 0,
    //   data: {},
    //   message: "xxx"
    // }

    // todo: debug 专用
    if (res.response && res.response.code === 0 && res.response.data) {
      console.log('extractData: \n', res.response.data)
    }

    // 优先取服务器返回的错误
    if (res.response && res.response.code !== 0) {
      throw res
    }

    return res.response ? res.response.data : null
  }

  /**
   * 接住各种请求错误, 显示给用户
   * @param res
   */
  handleError(res) {
    console.log('handleError res: \n', res)
    throw Error(
      res.response && res.response.message
        ? res.response.message
        : res.message
          ? res.message
          : '网络错误, 请刷新重试',
    )
  }

  // 请求后台给用户发验证码
  sendPhoneVerificationCode({ phone }) {

    // TODO: mock
    // return of(1)

    return this.get(`/webSite/sms/getPhoneVerifyCode?phone=${phone}`)
  }

  // 提交登录信息
  postLogin(payload) {

    // TODO: mock
    // return of(fakeUser)

    return this.post(`/webSite/login`, payload)
  }

  // 提交注册信息
  postRegister(payload) {
    return this.post(`/webSite/register`, payload)
  }


}

export default apiService
